package main

import (
	"fmt"
	"log/slog"
	"os"
	"time"

	"gorm.io/gorm"

	"github.com/gin-contrib/cors"
	"github.com/lab-online/config"
	app "github.com/lab-online/internal"
	"github.com/lab-online/pkg/database"
	"github.com/lab-online/pkg/middleware"
	"github.com/lab-online/pkg/mq"
	"github.com/lab-online/pkg/openapi"
	"github.com/tsingshaner/go-pkg/log"
	"github.com/tsingshaner/go-pkg/log/helper"
)

//	@title			在线实验平台
//	@version		1.0
//	@description	在线实验平台 API 文档
//	@description.markdown
//	@termsOfService	https://swagger.io/terms/

//	@securityDefinitions.apikey	bearer
//	@in							header
//	@name						Authorization

//	@contact.name	Issues
//	@contact.url	https://github.com/Jon-a-than/gin-template/issues

//	@license.name	MIT
//	@license.url	https://github.com/Jon-a-than/gin-template/blob/main/LICENSE

//	@externalDocs.description	ApiFox
//	@externalDocs.url			https://apifox.com/apidoc/shared-3e844af7-e01f-4a3a-a44d-9b395189d4d5
func main() {
	slogger, _ := log.NewSlog(os.Stdout, &log.SlogHandlerOptions{
		Level:     slog.Level(log.LevelAll),
		AddSource: true,
	})
	db := database.ConnectDB(config.Service.Postgres, &gorm.Config{
		Logger: helper.NewGormLogger(slogger, helper.GORMLoggerOptions{
			SlowThreshold:             200 * time.Millisecond,
			LogLevel:                  slog.Level(log.LevelAll),
			IgnoreRecordNotFoundError: true,
			ParameterizedQueries:      true,
		}),
	})
	messageQueue := mq.Connect(config.Service.RabbitMQ)

	corsConfig := cors.DefaultConfig()
	corsConfig.AllowOrigins = config.CORS.AllowOrigins
	corsConfig.AllowMethods = config.CORS.AllowMethods
	corsConfig.AllowHeaders = config.CORS.AllowHeaders
	corsConfig.AllowCredentials = config.CORS.AllowCredentials
	corsConfig.MaxAge = config.CORS.MaxAge * time.Minute

	serverApp := app.New(&app.Config{
		OSS:          config.OSSOptions,
		MessageQueue: messageQueue,
		Database:     db,
		JWT:          config.JWT,
		CORS:         corsConfig,
		Mode:         config.Server.Mode,
		HttpLogger: middleware.LoggerConfig{
			Console: &config.Logger.ConsoleHttp,
			Level:   &config.Logger.HttpLevel,
		},
	})

	serverAddr := fmt.Sprintf("%s:%d", config.Server.Host, config.Server.Port)

	if config.Server.EnableOpenAPI {
		openapi.Setup(serverApp.GetEngine(), &openapi.Config{
			DOCSPrefix: config.Server.OpenAPIRoute,
			ServerAddr: serverAddr,
			BasePath:   config.Server.Prefix,
		})
	}
	serverApp.Bootstrap(serverAddr, config.Server.Prefix)
	defer serverApp.Shutdown()
}
